<template>
  <el-drawer
      :title="'《' + epData.name + '》' + (tableType === 'raw' ? '生肉' : '熟肉')"
      size="500px"
      :visible.sync="visible"
      :append-to-body="true"
      :show-close="false"
      :before-close="handleClose"
      direction="ltr">
    <div id="drawer-main-box">
      <div class="table-top theme-border-bottom">
        <div class="button-box">
          <el-button class="theme-button" type="primary" size="mini" icon="el-icon-upload" circle
                     @click="$refs.file.click()"></el-button>
          <el-popover
              v-if="tableType === 'raw'"
              placement="top-start"
              title="请选择导出的内容"
              width="200"
              trigger="hover">
            <el-button type="primary" size="mini" circle @click="openDownloadNotice('TEXT')">文</el-button>
            <el-button type="primary" size="mini" circle @click="openDownloadNotice('IMG')">图</el-button>
            <el-button type="primary" size="mini" circle @click="openDownloadNotice('BLANK_IMG')">白</el-button>
            <el-button slot="reference" class="theme-button" type="primary" size="mini" icon="el-icon-download" circle></el-button>
          </el-popover>
          <el-button type="danger" size="mini" icon="el-icon-refresh-right" circle @click="clearFiles"/>
          <input style="opacity: 0; width: 0; height: 0;" multiple type="file" ref="file" @change="handleFileUpload"/>
          <input style="opacity: 0; width: 0; height: 0;" type="file" ref="singleFile"
                 @change="handleFileUpload($event, true)"/>
        </div>
        <span class="upload-box" v-if="showProgress">
          {{ uploadProgress < 100 ? '正在上传' + uploadCount + '个文件...' : uploadFinalText }}
        <el-progress style="width: 250px;" :percentage="uploadProgress" :color="customColors"
                     :status="uploadStatus"/>
        </span>
      </div>
      <empty-box v-if="fileList.length === 0" tip="暂无数据"/>
      <draggable v-else v-model="fileList" animation="1000" :disabled="isUploading" chosenClass="chosen"
                 @change="() => this.hvDrag = true">
        <transition-group class="table-content">
          <div class="file-item-box" v-for="(item) in fileList" :key="item.number">
            <div>
              <i class="move-icon"> &equiv;</i>
              <span>P{{ item.number }}</span>
              <el-divider direction="vertical"/>
              <span class="text-ellipsis">{{ getLastSegment(item.imageUrl, '/') }}</span>
            </div>
            <div>
              <el-popover
                  width="300"
                  placement="right"
                  trigger="hover">
                <img style="width: 100%;height: 100%;object-fit: fill;" loading="lazy" id="review-img"
                     :src="item.thumbUrl ? item.thumbUrl : item.imageUrl" alt=""/>
                <span slot="reference" class="btn el-icon-view"/>
              </el-popover>
              <span class="btn el-icon-upload" @click="reUpload(tableType === 'raw' ? item.epRid : item.epCid)"/>
              <span class="btn el-icon-delete" @click="deletedPage(tableType === 'raw' ? item.epRid : item.epCid)"/>
            </div>
          </div>
        </transition-group>
      </draggable>
    </div>
  </el-drawer>
</template>

<script>
import {
  clearCooked,
  clearRaw,
  cookedList,
  deletedCooked,
  deletedRaw, submitExport,
  rawList,
  reSortCookedList,
  reSortRawList, exportText
} from "@/api/mgEpApi";
import {getLastSegment} from "@/util/strUtil";
import request from "@/util/axios";
import draggable from "vuedraggable";
import {downloadFile} from "@/util/downloadUtil";

export default {
  name: "mangaEpPageDrawer",
  components: {draggable},
  data() {
    return {
      visible: false,
      tableType: 'raw',
      // 上传进度相关
      showProgress: false,
      isUploading: false,
      uploadProgress: 0,
      uploadFinalText: '已上传完毕，服务器君正在努力保存...',
      uploadStatus: null,
      customColors: [
        {color: '#909399', percentage: 40},
        {color: '#409eff', percentage: 99},
        {color: '#67c23a', percentage: 100}
      ],
      uploadCount: 0,
      currentPageId: -1,
      epData: {},
      fileList: [],
      // 是否有拖拽
      hvDrag: false,
    }
  },
  methods: {
    getLastSegment,
    openWindow(type, epData) {
      this.tableType = type
      this.epData = epData
      this.visible = true
      this.flashData()
    },
    handleClose() {
      this.reSort()
      this.visible = false
      this.$emit('flashData', this.epData.mangaId)
      this.epData = {}
      this.fileList = []
      this.tableType = 'raw'
      this.showProgress = false
      this.currentPageId = -1
    },
    flashData() {
      if (this.tableType === 'raw') {
        // 请求生肉列表
        rawList(this.epData.epId).then(res => {
          this.fileList = res.data
        })
      } else {
        // 请求熟肉列表
        cookedList(this.epData.epId).then(res => {
          this.fileList = res.data
        })
      }
    },
    openDownloadNotice(type) {
      let title = ''
      let raw = false
      let blank = false
      switch (type) {
        case 'TEXT':
          title = '导出翻译文本'
          break;
        case 'IMG':
          title = '导出生肉'
          raw = true
          break;
        case 'BLANK_IMG':
          title = '导出制作好的大白框'
          blank = true
          break;
      }
      this.$confirm(title, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }).then(() => {
        if (type === 'TEXT') {
          exportText(this.epData.epId).then(res => downloadFile(res))
        } else {
          let params = {
            epId: this.epData.epId,
            raw: raw,
            blank: blank,
            cooked: false
          }
          submitExport(params).then(res => {
            if (res.code === '200') {
              this.$notify({
                type: 'success',
                title: '提示',
                message: '已添加到导出队列',
                position: 'top-right'
              });
            }
          })
        }
      });
    },
    /**
     * 删除页面
     * @param pageId 页面id
     */
    deletedPage(pageId) {
      this.$confirm('此操作将永久删除该页码, 是否继续?', {
        type: 'warning',
      }).then(() => {
        if (this.tableType === 'raw') {
          deletedRaw(this.epData.epId, pageId).then(res => {
            if (res.code === '200') {
              this.$message.success('删除成功')
              this.flashData()
            }
          })
        } else {
          deletedCooked(this.epData.epId, pageId).then(res => {
            if (res.code === '200') {
              this.$message.success('删除成功')
              this.flashData()
            }
          })
        }
      })
    },
    async reSort() {
      if (this.hvDrag) {
        // 准备数据
        let data = {
          epId: this.epData.epId,
          sortList: []
        }
        this.fileList.forEach((item, index) => {
          data.sortList.push({
            pageId: this.tableType === 'raw' ? item.epRid : item.epCid,
            number: index + 1
          })
        })
        if (this.tableType === 'raw') {
          await reSortRawList(data)
        } else {
          await reSortCookedList(data)
        }
      }
    },
    /**
     * 重新上传
     * @param pageId 页面id
     */
    reUpload(pageId) {
      this.currentPageId = pageId
      this.$refs.singleFile.click()
    },
    /**
     * 清空文件
     */
    clearFiles() {
      this.$confirm('此操作将清空该章节所有图片, 是否继续?', {
        type: "warning"
      }).then(() => {
        if (this.tableType === 'raw') {
          clearRaw(this.epData.epId).then(res => {
            if (res.code === '200') {
              this.$message.success('清空成功')
              this.flashData()
            }
          })
        } else {
          clearCooked(this.epData.epId).then(res => {
            if (res.code === '200') {
              this.$message.success('清空成功')
              this.flashData()
            }
          })
        }
      })
    },
    /**
     * 初始化进度条
     */
    initProgress() {
      this.uploadFinalText = '已上传完毕，服务器君正在努力保存...'
      this.uploadStatus = null
      this.showProgress = true
      this.customColors[2].color = '#67c23a'
    },
    /**
     * 文件上传
     * @param event 事件
     * @param isSingle 是否单文件
     */
    handleFileUpload(event, isSingle = false) {
      if (this.fileList.length >= 250) {
        this.$message.error('当前章节已达到最大页数，请分章节上传')
        return
      }
      // 获取选择文件
      let files = event.target.files || event.dataTransfer.files;
      if (files.length === 0) return
      if (files.length > 100) {
        this.$message.error('一次最多只能上传100张图片, 请分批上传')
        return
      }
      // 准备请求地址和表单数据
      let formData = new FormData();
      let url
      if (isSingle) {
        url = this.tableType === 'raw' ? '/api/manga/ep/reUploadRawMg' : '/api/manga/ep/reUploadCookedMg'
        formData.append('pageId', this.currentPageId)
      } else {
        url = this.tableType === 'raw' ? '/api/manga/ep/uploadRawMg' : '/api/manga/ep/uploadCookedMg'
      }
      formData.append('epId', this.epData.epId)
      // 检查文件
      let totalSize = 0;
      for (let i = 0; i < files.length; i++) {
        // 判断文件类型
        if (!files[i].type.includes('image')) {
          this.$message.error('上传图片只能是 PNG/JPG 格式!');
          return;
        }
        // 判断文件大小
        let fileSize = files[i].size;
        if (fileSize > 1024 * 1024 * 2) {
          this.$message.error('单文件不能大于2MB!');
          return;
        }
        totalSize += fileSize;
        this.uploadCount++;
        formData.append('files', files[i])
      }
      // 判断文件大小
      if (totalSize > 1024 * 1024 * 200) {
        this.$message.error('单次上传图片总大小不能超过 200MB!');
        return;
      }

      /**
       * 失败的进度条样式
       */
      function failProgress() {
        this.customColors[2].color = '#F56C6C'
        this.uploadFinalText = '失败'
        this.uploadStatus = 'exception'
      }

      this.isUploading = true
      // 发送请求
      request({
        method: 'post',
        url: url,
        headers: {
          'Content-Type': 'multipart/form-data;charset=UTF-8'
        },
        data: formData,
        timeout: 0,
        // 监听进度
        onUploadProgress: (e) => {
          this.initProgress();
          this.uploadProgress = Number((e.loaded / e.total * 100).toFixed(0))
        }
      }).then(res => {
        if (res.code === '200') {
          // 成功修改样式与文案，并刷新列表
          this.uploadStatus = 'success'
          this.uploadFinalText = '成功'
          this.flashData()
        } else {
          failProgress.call(this);
        }
      }, () => {
        failProgress.call(this);
      }).finally(() => {
        this.isUploading = false
        this.initProgress()
        this.uploadCount = 0
      })
    }
  },
}
</script>

<style scoped lang="scss">
#drawer-main-box {
  width: 100%;
  height: 100%;
  padding: 0 20px 0 20px;
  display: flex;
  flex-direction: column;
  justify-items: flex-start;

  .table-top {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 15px;

    .button-box {
      button {
        margin-right: 5px;
      }
    }

    .upload-box {
      font-size: small;
      color: #909399;
      transition: all 0.3s ease;
    }
  }

  .table-content {
    width: 100%;
    height: 80vh;
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    overflow: hidden;
    overflow-y: auto;
    margin-top: 10px;
    border-bottom: 1px solid #ebeef5;

    .file-item-box {
      width: 100%;
      height: 35px;
      display: flex;
      border-bottom: 1px solid #ebeef5;
      transition: all 0.5s ease; /* 添加过渡效果，0.5秒内平滑过渡 */
      align-items: center;
      justify-content: space-between;
      font-size: 15px;
      padding: 5px 0;

      .move-icon {
        color: rgba(0, 0, 0, 0.5);
        cursor: move;
        padding-right: 10px;
      }

    }

    .chosen {
      border: 1px solid #409EFF;
      background-color: #f5f7fa;
    }

    .file-item-box {
      width: 100%;
      height: 40px;
      padding: 0 10px;

      .btn {
        padding-left: 10px;
        cursor: pointer;
      }

      .el-icon-upload:hover {
        color: #409EFF;
      }

      .el-icon-view:hover {
        color: #409EFF;
      }

      .el-icon-delete:hover {
        color: #F56C6C;
      }

    }

    .file-item-box:hover {
      background-color: #f5f7fa;
    }

    /* 滚动条背景 */
    &::-webkit-scrollbar {
      width: 7px;
      height: 7px;
      border-radius: 5px;
      background-color: rgb(245, 245, 245, 0.5);
    }

    /* 滑块 */
    &::-webkit-scrollbar-thumb {
      border-radius: 5px;
      background-color: var(--theme-color);
    }
  }
}
</style>